package com.robgfx.opensail.test;

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.net.URL;
import java.util.Set;
import java.util.logging.Logger;

import javax.swing.JComboBox;
import javax.swing.JComponent;

import com.jme.app.BaseSimpleGame;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.system.PropertiesIO;
import com.jme.system.lwjgl.LWJGLPropertiesDialog;
import com.jme.util.geom.Debugger;
import com.jmex.physics.PhysicsDebugger;
import com.jmex.physics.PhysicsSpace;

public abstract class PassPhysicsGame extends BaseSimpleGame {

	private PhysicsSpace physicsSpace;
	protected InputHandler cameraInputHandler;

	private float physicsSpeed = 1;

	/**
	 * @return speed set by {@link #setPhysicsSpeed(float)}
	 */
	public float getPhysicsSpeed() {
		return physicsSpeed;
	}

	/**
	 * The multiplier for the physics time. Default is 1, which means normal speed. 0 means no physics processing.
	 * @param physicsSpeed new speed
	 */
	public void setPhysicsSpeed( float physicsSpeed ) {
		this.physicsSpeed = physicsSpeed;
	}

	@Override
	protected void initSystem() {
		super.initSystem();

		/** Create a basic input controller. */
		cameraInputHandler = new FirstPersonHandler( cam, 50, 1 );
		input = new InputHandler();
		input.addToAttachedHandlers( cameraInputHandler );

		setPhysicsSpace( PhysicsSpace.create() );

		input.addAction( new InputAction() {
			public void performAction( InputActionEvent evt ) {
				if ( evt.getTriggerPressed() ) {
					showPhysics = !showPhysics;
				}
			}
		}, InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_V, InputHandler.AXIS_NONE, false );
	}

	/**
	 * @return the physics space for this simple game
	 */
	public PhysicsSpace getPhysicsSpace() {
		return physicsSpace;
	}

	/**
	 * @param physicsSpace The physics space for this simple game
	 */
	protected void setPhysicsSpace(PhysicsSpace physicsSpace) {
		if ( physicsSpace != this.physicsSpace ) {
			if ( this.physicsSpace != null )
				this.physicsSpace.delete();
			this.physicsSpace = physicsSpace;
		}
	}

	private boolean firstFrame = true;

	/**
	 * Called every frame to update scene information.
	 *
	 * @param interpolation unused in this implementation
	 * @see BaseSimpleGame#update(float interpolation)
	 */
	@Override
	protected final void update( float interpolation ) {
		// disable input as we want it to be updated _after_ physics
		// in your application derived from BaseGame you can simply make the call to InputHandler.update later
		// in your game loop instead of this disabling and reenabling

		super.update( interpolation );

		if ( !pause ) {
			float tpf = this.tpf;
			if ( tpf > 0.2 || Float.isNaN( tpf ) ) {
				Logger.getLogger( PhysicsSpace.LOGGER_NAME ).warning( "Maximum physics update interval is 0.2 seconds - capped." );
				tpf = 0.2f;
			}
			getPhysicsSpace().update( tpf * physicsSpeed );
		}

		input.update( tpf );

		if ( !pause ) {
			

			/** Update controllers/render states/transforms/bounds for rootNode. */
			rootNode.updateGeometricState( tpf, true );
			fpsNode.updateGeometricState(tpf, true);
			
			pManager.updatePasses(tpf);
			
			/** Call simpleUpdate in any derived classes of SimpleGame. */
			simpleUpdate();
		}

		if ( firstFrame )
		{
			// drawing and calculating the first frame usually takes longer than the rest
			// to avoid a rushing simulation we reset the timer
			timer.reset();
			firstFrame = false;
		}
	}

	@Override
	protected void updateInput() {
		// don't input here but after physics update
	}

	protected boolean showPhysics;
	protected BasicPassManager pManager;

	/**
	 * This is called every frame in BaseGame.start(), after update()
	 *
	 * @param interpolation unused in this implementation
	 * @see com.jme.app.AbstractGame#render(float interpolation)
	 */
	@Override
	protected final void render( float interpolation ) {
		super.render( interpolation );

		preRender();

		Renderer r = display.getRenderer();

		/** Have the PassManager render. */
        pManager.renderPasses(r);
        
		/** Call simpleRender() in any derived classes. */
		simpleRender();


//		/** Draw the rootNode and all its children. */
//		r.draw( rootNode );
//		
//		/** Draw the fps node to show the fancy information at the bottom. */
//		r.draw( fpsNode );
		
		if ( showDepth ) {
	        
//			r.renderQueue();
			Debugger.drawBuffer( Texture.RTT_SOURCE_DEPTH, Debugger.NORTHEAST, r );
		}
		

		doDebug(r);
	}

	protected void preRender() {

	}

	@Override
	protected void doDebug(Renderer r) {
		super.doDebug(r);

		if ( showPhysics ) {
			PhysicsDebugger.drawPhysics( getPhysicsSpace(), r );
		}

		if (showDepth) {
			r.renderQueue();
			Debugger.drawBuffer(Texture.RTT_SOURCE_DEPTH, Debugger.NORTHEAST, r);
		}
	}
	
    /**
     * Creates pass manager then calls super.initGame();
     * 
     * @see BaseSimpleGame#initGame()
     */
    protected final void initGame() {
        pManager = new BasicPassManager();
        
        super.initGame();
    }
    
}
